package com.fastbee.web.wnx;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 对接万年芯接口平台 谭增杰 2025-11-12
 */
public class GetWnxApiData {
    private static final Logger log = LoggerFactory.getLogger(GetWnxApiData.class);

    private static final String API_SECRET_CODE = "6PHGeJc5pYi9dbMpIgb5TZ4xV4kPpl6d";
    private static final String BASE_URL = "http://192.168.10.99:8080/pro";
    private static final String JOB_NUM = "W01030";
    private static final String PASSWORD = "123456";


    /**
     * 修复乱码问题的HTTP请求方法
     */
    public static String sendPostRequestFixed(String urlString, String jsonData) throws IOException {
        HttpURLConnection connection = null;
        String apiUrl = BASE_URL + urlString;
        System.out.println("API地址: " + BASE_URL);
        try {
            URL url = new URL(apiUrl);
            connection = (HttpURLConnection) url.openConnection();

            // 设置请求属性
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            connection.setRequestProperty("Accept", "application/json; charset=UTF-8");
            connection.setRequestProperty("User-Agent", "Java-API-Client");
            connection.setDoOutput(true);
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(30000);

            // 发送请求数据
            try (OutputStream os = connection.getOutputStream()) {
                byte[] input = jsonData.getBytes(StandardCharsets.UTF_8);
                os.write(input, 0, input.length);
                os.flush();
            }

            // 获取响应代码和ContentType
            int responseCode = connection.getResponseCode();
            String contentType = connection.getContentType();
            System.out.println("HTTP响应代码: " + responseCode);
            System.out.println("Content-Type: " + contentType);

            // 检测实际编码（重点修复）
            String charset = detectActualCharset(connection);
            System.out.println("检测到实际编码: " + charset);

            // 读取响应内容
            InputStream inputStream = (responseCode == 200) ?
                    connection.getInputStream() : connection.getErrorStream();

            if (inputStream == null) {
                return "无响应内容";
            }

            // 使用检测到的编码读取
            return  GetWnxApiData.decodeUnicode(readResponseWithCharset(inputStream, charset));
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 检测实际的字符编码
     */
    private static String detectActualCharset(HttpURLConnection connection) {
        try {
            // 方法1: 从Content-Type头获取
            String contentType = connection.getContentType();
            if (contentType != null && contentType.contains("charset=")) {
                String charset = contentType.substring(contentType.indexOf("charset=") + 8);
                if (charset.contains(";")) {
                    charset = charset.substring(0, charset.indexOf(";"));
                }
                charset = charset.trim();
                if (!charset.isEmpty()) {
                    return charset;
                }
            }

            // 方法2: 尝试读取前几个字节来检测BOM标记
            InputStream is = connection.getInputStream();
            if (is.markSupported()) {
                is.mark(4);
                byte[] bom = new byte[3];
                int read = is.read(bom);
                is.reset();

                if (read >= 3) {
                    // 检查UTF-8 BOM: EF BB BF
                    if (bom[0] == (byte)0xEF && bom[1] == (byte)0xBB && bom[2] == (byte)0xBF) {
                        return "UTF-8";
                    }
                    // 检查UTF-16 BE BOM: FE FF
                    if (bom[0] == (byte)0xFE && bom[1] == (byte)0xFF) {
                        return "UTF-16BE";
                    }
                    // 检查UTF-16 LE BOM: FF FE
                    if (bom[0] == (byte)0xFF && bom[1] == (byte)0xFE) {
                        return "UTF-16LE";
                    }
                }
            }

        } catch (Exception e) {
            System.out.println("编码检测失败: " + e.getMessage());
        }

        // 方法3: 常见编码尝试
        String[] commonCharsets = {"UTF-8", "GBK", "GB2312", "ISO-8859-1", "US-ASCII"};
        for (String charset : commonCharsets) {
            try {
                // 简单验证编码是否可用
                "test".getBytes(charset);
                return charset;
            } catch (UnsupportedEncodingException e) {
                // 跳过不支持的编码
            }
        }

        return "UTF-8"; // 默认回退到UTF-8
    }

    /**
     * 使用指定编码读取响应
     */
    private static String readResponseWithCharset(InputStream inputStream, String charset) throws IOException {
        try (ByteArrayOutputStream result = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }

            byte[] responseBytes = result.toByteArray();
            System.out.println("响应字节长度: " + responseBytes.length);

            // 尝试用检测到的编码解码
            try {
                return new String(responseBytes, charset);
            } catch (UnsupportedEncodingException e) {
                System.out.println("编码 " + charset + " 不支持，尝试UTF-8");
                return new String(responseBytes, StandardCharsets.UTF_8);
            }
        }
    }

    /**
     * 解码Unicode转义序列（处理\u8D26\u53F7这种格式）
     */
    static String decodeUnicode(String unicodeString) {
        if (unicodeString == null || unicodeString.isEmpty()) {
            return unicodeString;
        }

        StringBuilder decoded = new StringBuilder();
        int length = unicodeString.length();
        int pos = 0;

        while (pos < length) {
            char ch = unicodeString.charAt(pos);
            if (ch == '\\' && pos + 5 < length && unicodeString.charAt(pos + 1) == 'u') {
                // 找到\\u转义序列
                try {
                    String hex = unicodeString.substring(pos + 2, pos + 6);
                    char unicodeChar = (char) Integer.parseInt(hex, 16);
                    decoded.append(unicodeChar);
                    pos += 6;
                } catch (NumberFormatException e) {
                    decoded.append(ch);
                    pos++;
                }
            } else {
                decoded.append(ch);
                pos++;
            }
        }

        return decoded.toString();
    }

    /**
     * 生成数字签名token
     */
    public static String generateToken(long timestamp, Map<String, String> paraMap){
        if(paraMap == null){
            paraMap=new HashMap<>();
        }
        paraMap.put("apisecretcode", API_SECRET_CODE);
        paraMap.put("timestamp", String.valueOf(timestamp));
//        paraMap.put("JobNum", JOB_NUM);
//        paraMap.put("PassWord", PASSWORD);

        List<String> keyList = new ArrayList<>(paraMap.keySet());
        Collections.sort(keyList);

        StringBuilder paraString = new StringBuilder();
        for (String key : keyList) {
            paraString.append(key).append(":").append(paraMap.get(key)).append(";");
        }

        System.out.println("签名参数字符串: " + paraString.toString());
        return DigestUtils.md5DigestAsHex(paraString.toString().getBytes(StandardCharsets.UTF_8)).toLowerCase();
    }

    /**
     * 构建请求JSON数据
     */
    static String buildRequestJson(long timestamp, String token) {
        return String.format("{\"timestamp\":%s,\"timestamp\":%d,\"token\":\"%s\"}"
                , DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"),timestamp, token);
    }

}
